#include"get_weather.h"

// 1. 全局LVGL组件定义
lv_obj_t *ui_WeatherCity;
lv_obj_t *ui_WeatherInfo;
lv_obj_t *ui_WeatherIcon;
//字体声明
LV_FONT_DECLARE(lv_font_fan_24);

// 2. 天气英文转中文（不变）
const char* weather_en_to_cn(const char* en_weather) {
    if (!en_weather) return "未知";
    if (strcmp(en_weather, "clear") == 0) return "晴";
    if (strcmp(en_weather, "partly cloudy") == 0) return "多云";
    if (strcmp(en_weather, "cloudy") == 0) return "阴";
    if (strcmp(en_weather, "light rain") == 0) return "小雨";
    if (strcmp(en_weather, "moderate rain") == 0) return "中雨";
    if (strcmp(en_weather, "heavy rain") == 0) return "大雨";
    if (strcmp(en_weather, "thunderstorm") == 0) return "雷阵雨";
    if (strcmp(en_weather, "snow") == 0) return "雪";
    return en_weather;
}

// 3. 匹配天气图标（返回图标地址）
const char* get_weather_icon(const char* weather_cn) {
    if (strcmp(weather_cn, "晴") == 0) return (const char*)&SUN;
    if (strcmp(weather_cn, "多云") == 0) return (const char*)&DUOYUN;
    if (strcmp(weather_cn, "阴") == 0) return (const char*)&YINTIAN;
    if (strstr(weather_cn, "雨") != NULL) return (const char*)&YUTIAN;
    if (strcmp(weather_cn, "雪") == 0) return (const char*)&SNOW;
    return (const char*)&LOAD; // 默认加载中图标
}

// 4. 单次获取天气数据
int get_weather_once(WeatherData *data) {
    if (!data) return -1;

    // 4.1 创建Socket
    int cli_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (cli_fd == -1) {
        perror("socket create fail");
        return -1;
    }

    // 4.2 域名解析（心知天气API）
    struct hostent *he = gethostbyname("api.seniverse.com");
    if (!he) {
        perror("host resolve fail");
        close(cli_fd);
        return -1;
    }

    // 4.3 配置服务器地址
    struct sockaddr_in ser_addr;
    memset(&ser_addr, 0, sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(80); 
    ser_addr.sin_addr = *((struct in_addr *)he->h_addr_list[0]);

    // 4.4 连接服务器
    if (connect(cli_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) == -1) {
        perror("connect fail");
        close(cli_fd);
        return -1;
    }

    // 4.5 构造HTTP请求
    char loc_city[50] = "广州";
    char request[1024];
    sprintf(request, 
            "GET /v3/weather/now.json?key=SN_g1fbWfLIKumOcf&location=%s&language=zh-Hans&unit=c HTTP/1.1\r\n"
            "Host: api.seniverse.com\r\n"
            "Connection: close\r\n\r\n", 
            loc_city);

    // 4.6 发送请求
    if (write(cli_fd, request, strlen(request)) == -1) {
        perror("write fail");
        close(cli_fd);
        return -1;
    }

    // 4.7 读取响应头（找到\r\n\r\n结束）
    char resp_buf[4096] = {0};
    int pos = 0;
    ssize_t n;
    while (pos < sizeof(resp_buf)-1) {
        n = read(cli_fd, resp_buf + pos, 1);
        if (n <= 0) break;
        pos++;
        if (strstr(resp_buf, "\r\n\r\n")) break;
    }

    // 4.8 检查HTTP状态码（200为成功）
    char *status_str = strstr(resp_buf, "HTTP/1.");
    if (!status_str) {
        printf("status parse fail\n");
        close(cli_fd);
        return -1;
    }
    int status = atoi(status_str + 9);
    if (status < 200 || status >= 300) {
        printf("http status error: %d\n", status);
        close(cli_fd);
        return -1;
    }

    // 4.9 解析响应体长度
    char *len_str = strstr(resp_buf, "Content-Length: ");
    if (!len_str) {
        printf("content length parse fail\n");
        close(cli_fd);
        return -1;
    }
    int content_len = atoi(len_str + strlen("Content-Length: "));
    if (content_len <= 0) {
        close(cli_fd);
        return -1;
    }

    // 4.10 读取响应体（跳过响应头）
    char *content = malloc(content_len + 1);
    if (!content) {
        perror("malloc fail");
        close(cli_fd);
        return -1;
    }
    memset(content, 0, content_len + 1);

    char *body_start = strstr(resp_buf, "\r\n\r\n");
    int body_in_header = 0;
    if (body_start) {
        body_start += 4; // 跳过\r\n\r\n
        body_in_header = pos - (body_start - resp_buf);
        if (body_in_header > 0) {
            memcpy(content, body_start, body_in_header);
            content_len -= body_in_header;
        }
    }

    // 读取剩余响应体
    int total_read = body_in_header;
    while (total_read < (body_in_header + content_len)) {
        n = read(cli_fd, content + total_read, content_len - (total_read - body_in_header));
        if (n <= 0) break;
        total_read += n;
    }

    // 4.11 解析JSON数据
    cJSON *root = cJSON_Parse(content);
    if (root) {
        cJSON *results = cJSON_GetObjectItem(root, "Results");
        if (results && cJSON_IsArray(results) && cJSON_GetArraySize(results) > 0) {
            cJSON *result = cJSON_GetArrayItem(results, 0);
            cJSON *loc = cJSON_GetObjectItem(result, "Location");
            cJSON *now = cJSON_GetObjectItem(result, "Now");

            if (loc && now) {
                cJSON *city = cJSON_GetObjectItem(loc, "Name");
                cJSON *wea = cJSON_GetObjectItem(now, "Text");
                cJSON *temp = cJSON_GetObjectItem(now, "Temperature");

                if (city && wea && temp) {
                    strncpy(data->city, city->valuestring, sizeof(data->city)-1);
                    strncpy(data->weather, weather_en_to_cn(wea->valuestring), sizeof(data->weather)-1);
                    strncpy(data->temp, temp->valuestring, sizeof(data->temp)-1);
                }
            }
        }
        cJSON_Delete(root); // 释放JSON内存
    }

    // 4.12 资源清理
    free(content);
    close(cli_fd);
    return 0;
}

// 5. 刷新天气界面（LVGL主线程调用）
void lv_refresh_weather(void *arg) {
    WeatherData *data = (WeatherData *)arg;
    char info_buf[50];

    // 更新标签和图标
    lv_label_set_text(ui_WeatherCity, data->city);
    sprintf(info_buf, "%s %s°C", data->weather, data->temp);
    lv_label_set_text(ui_WeatherInfo, info_buf);
    lv_img_set_src(ui_WeatherIcon, get_weather_icon(data->weather));
}

// 6. 刷新失败界面
void lv_refresh_weather_fail(void *arg) {
    lv_label_set_text(ui_WeatherCity, "获取失败");
    lv_label_set_text(ui_WeatherInfo, "检查网络");
    lv_img_set_src(ui_WeatherIcon, (const char*)&ERROR);
}

// 7. 天气更新线程（子线程，返回void*）
void *update_weather_loop(void *arg) {
    WeatherData data;
    while (1) {
        if (get_weather_once(&data) == 0) {
            // 关键修正：LVGL v8.3用lv_async_call替代lv_invoker_send（主线程安全刷新）
            lv_async_call(lv_refresh_weather, &data);
        } else {
            lv_async_call(lv_refresh_weather_fail, NULL);
        }
        sleep(1800); // 每30分钟更新一次
    }
    return NULL; // 线程函数必须返回值
}

// 8. 创建天气组件(screen4)
void ui_WeatherComponent_Create(lv_obj_t *parent) {
    // 8.1 天气容器
    lv_obj_t *weather_cont = lv_obj_create(parent);
    lv_obj_set_size(weather_cont, 200, 70);
    lv_obj_set_align(weather_cont, LV_ALIGN_CENTER);
    lv_obj_set_x(weather_cont, -420); // 位置：屏幕左侧
    lv_obj_set_y(weather_cont, -250); // 位置：屏幕上方
    lv_obj_clear_flag(weather_cont, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_style_bg_opa(weather_cont, 0, LV_PART_MAIN); // 透明背景

    // 8.2 天气图标
    ui_WeatherIcon = lv_img_create(weather_cont);
    lv_obj_set_size(ui_WeatherIcon, 70, 50);
    lv_obj_set_align(ui_WeatherIcon, LV_ALIGN_LEFT_MID);
    lv_obj_set_x(ui_WeatherIcon, 10);
    lv_img_set_src(ui_WeatherIcon, (const char*)&LOAD); // 初始加载中

    // 8.3 城市标签
    ui_WeatherCity = lv_label_create(weather_cont);
    lv_obj_set_align(ui_WeatherCity, LV_ALIGN_TOP_RIGHT);
    lv_obj_set_x(ui_WeatherCity, -10);
    lv_obj_set_y(ui_WeatherCity, 10);
    lv_label_set_text(ui_WeatherCity, "加载中...");
    lv_obj_set_style_text_font(ui_WeatherCity, &lv_font_fan_24, LV_PART_MAIN);
    lv_obj_set_style_text_color(ui_WeatherCity, lv_color_hex(0x333333), LV_PART_MAIN);

    // 8.4 天气+温度标签
    ui_WeatherInfo = lv_label_create(weather_cont);
    lv_obj_set_align(ui_WeatherInfo, LV_ALIGN_BOTTOM_RIGHT);
    lv_obj_set_x(ui_WeatherInfo, -10);
    lv_obj_set_y(ui_WeatherInfo, -10);
    lv_label_set_text(ui_WeatherInfo, "");
    lv_obj_set_style_text_font(ui_WeatherInfo, &lv_font_fan_24, LV_PART_MAIN);
    lv_obj_set_style_text_color(ui_WeatherInfo, lv_color_hex(0x666666), LV_PART_MAIN);

    // 8.5 启动更新线程
    pthread_t tid;
    pthread_create(&tid, NULL, update_weather_loop, NULL);
}

// 9. 你声明的Weather_display函数（空实现，可根据需求扩展）
int Weather_display() {
    // 可添加额外的显示逻辑，比如日志打印
    printf("Weather display function called\n");
    return 0;
}